package com.ksvip.next.components.redis.retry;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import com.github.rholder.retry.Retryer;
import com.github.rholder.retry.RetryerBuilder;
import com.github.rholder.retry.StopStrategies;
import com.github.rholder.retry.WaitStrategies;
import com.google.common.base.Predicates;

/**
 * 构造重试器
 */
public class RedisRetryerBuilder {

    public static <V> Retryer<V> build() {
        //定义重试机制
        final Retryer<V> retryer = RetryerBuilder.<V> newBuilder()
                //retryIf 重试条件
                .retryIfExceptionOfType(Exception.class)
                .retryIfException(Predicates.equalTo(new Exception()))
//                .retryIfResult(Predicates.equalTo(false))
                .retryIfExceptionOfType(TimeoutException.class)
                .retryIfException()
                .retryIfRuntimeException()
                //等待策略：每次请求间隔1s
                .withWaitStrategy(WaitStrategies.fixedWait(1, TimeUnit.SECONDS))
                //停止策略 : 尝试请求3次
                .withStopStrategy(StopStrategies.stopAfterAttempt(5))
                //时间限制 : 某次请求不得超过2s , 类似: TimeLimiter timeLimiter = new SimpleTimeLimiter();
                //.withAttemptTimeLimiter((AttemptTimeLimiter<V>) AttemptTimeLimiters.fixedTimeLimit(2, TimeUnit.SECONDS))
                //默认的阻塞策略：线程睡眠
                //.withBlockStrategy(BlockStrategies.threadSleepStrategy())
                //自定义阻塞策略：自旋锁
                .withBlockStrategy(new SpinBlockStrategy())
                //自定义重试监听器
                .withRetryListener(new RetryLogListener()).build();
        return retryer;

    }
}
